using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;

public class VisualMisc : MonoBehaviour
{
	// Initialization before void Start()
	void Awake()
	{
		
	}

	// Use this for initialization
	void Start ()
	{

	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	public static List<GameObject> VisualImplStars(StarSystem star)
	{
		List<StarSystem> lss = new List<StarSystem>();
		lss.Add(star);

		return VisualImplStars(lss);
	}

	public static List<GameObject> VisualImplStars(List<StarSystem> solars)
	{
		Vector3 vpt;
		List <GameObject> gol = new List<GameObject>();		// to store center sun as light

		// to adjust font size in accordance to window size
		// Unity 2.6 doesn't support font change on the run
		Resolution res = Screen.currentResolution;
		double fsize = 0.0;

		if (res.width > 0)
		{
			switch (res.width)
			{
				case 800: fsize = 0.18; break;
				case 1024: fsize = 0.15; break;
				case 1280: fsize = 0.12; break;
			}
		}

		if (fsize > 0)
			Galaxy.ScreenRes = (int)res.width;			// running in window mode instead of full screen

		// visualize the star systems
		foreach (StarSystem ss in solars)
		{
			Vector3 centerpt = new Vector3(ss.Location.X, ss.Location.Y, ss.Location.Z);

			// to create the Sunlight object of which the planets surrounding
			// Sunlight also acts as the light source shining the planets
			GameObject obl = new GameObject();
			obl.AddComponent<Light>();

			if (obl == null)
			{
				Debug.Log("light failed to load!");
				return gol;
			}

			obl.name = "Light" + ss.StarID.ToString("D3");
			obl.transform.position = centerpt;
			obl.light.type = LightType.Point;
			obl.tag = "Sunlight";
			obl.light.range = 10;
			obl.light.intensity = 0.8f;

			GameObject obs = (GameObject)Instantiate(Resources.Load("Heatlight"));

			obs.name = "Heat" + ss.StarID.ToString("D3");
			obs.transform.position = centerpt;
			obs.light.type = LightType.Point;
			obs.tag = "Heatlight";
			obs.light.range = 0;
			obs.light.intensity = 1;


			switch (ss.Heat)
			{
				case StarSystem.SolarHeat.Grey: obs.light.color = Color.grey; break;
				case StarSystem.SolarHeat.Brown: obs.light.color = Color.yellow + Color.red + Color.grey; break;
				case StarSystem.SolarHeat.White: obs.light.color = Color.white; break;
				case StarSystem.SolarHeat.Green: obs.light.color = Color.green; break;
				case StarSystem.SolarHeat.Blue: obs.light.color = Color.blue; break;
				case StarSystem.SolarHeat.Yellow: obs.light.color = Color.yellow; break;
				case StarSystem.SolarHeat.Orange: obs.light.color = Color.yellow + Color.red; break;
				case StarSystem.SolarHeat.Purple: obs.light.color = Color.red + Color.blue; break;
				case StarSystem.SolarHeat.Red: obs.light.color = Color.red; break;

				default: obs.light.color = Color.magenta; break;
			}

			foreach (Planet pl in ss.Planets)
			{
				vpt = GetOrbitVector(ss.Location, pl.Orbit, Utility.RandomDouble() * Math.PI * 2);

				// GameObject star = GameObject.CreatePrimitive(PrimitiveType.Sphere);
				GameObject star = (GameObject)Instantiate(Resources.Load("star"));
	
				star.transform.position = vpt;
				star.name = pl.PlanetID;
				star.tag = "Planet";
	
				double orb = pl.Giant ? 1.25 : 0.5 + 0.15 * (int)pl.Size;
				
				star.transform.localScale = new Vector3( (float)orb, (float)orb, (float)orb );
				star.GetComponent<SphereCollider>().radius = orb > 1.0 ? (float)orb : 1.0f;

				switch (pl.Climate)
				{
						case Planet.PlanetClimate.Uninhabitable: { star.renderer.material.mainTexture = pl.Giant ? (Texture)Resources.Load("gasgiant") : 
						(Texture)Resources.Load("uninhabitable"); break; }
						case Planet.PlanetClimate.Polluted: star.renderer.material.mainTexture = (Texture)Resources.Load("polluted"); break;
						case Planet.PlanetClimate.Barren: star.renderer.material.mainTexture = (Texture)Resources.Load("barren"); break;
						case Planet.PlanetClimate.Desert: star.renderer.material.mainTexture = (Texture)Resources.Load("desert"); break;
						case Planet.PlanetClimate.Tundra: star.renderer.material.mainTexture = (Texture)Resources.Load("tundra"); break;
						case Planet.PlanetClimate.Ocean: star.renderer.material.mainTexture = (Texture)Resources.Load("ocean"); break;
						case Planet.PlanetClimate.Swamp: star.renderer.material.mainTexture = (Texture)Resources.Load("swamp"); break;
						case Planet.PlanetClimate.Terran: star.renderer.material.mainTexture = (Texture)Resources.Load("terran"); break;
						case Planet.PlanetClimate.Gaia: star.renderer.material.mainTexture = (Texture)Resources.Load("gaia"); break;

						default: break;
				}

				// to store visual star to non-visual planet object
				pl.Star = star;
				pl.Sun = obl;

				// to allow planet to run in orbit
				PlanetOrbit script = star.GetComponent<PlanetOrbit>();
				script.planet = pl;
				script.sun = obs;
				script.speed = (float)pl.Speed;

				// to enable the visual moving
				script.toRun = true;			// such that TrailRenderer will take effect

				// an initial run
				star.transform.RotateAround(centerpt, Vector3.up, (float)Utility.Random(359));

			}
		

			gol.Add( obl );
			ss.Sunlight = obl;				// obl is stored in starsystem, obs is stored in script PlanetOrbit

		}

		return gol;
	}
	
	public static Vector3 GetOrbitVector(Point3D point, int orbit, double angle)
	{
		double near = 0.5;
		double between = 1.5;
		
		double length = near + orbit * between;
		
		double x = point.X + length;
		double y = point.Y;
		double z = point.Z;

		return new Vector3((float)x, (float)y, (float)z);
	}

	public static bool RunStopStarSystem(StarSystem star, bool flag)
	{
		PlanetOrbit script;
		GameObject otext;
		GameObject ospot;
		string sname = "";

		for (int i = 0; i < 5; i++)
		{
			// to reset label objects
			sname = "Label" + (i + 1).ToString();
			otext = GameObject.Find(sname);
			otext.GetComponent<GUIText>().text = "";
		}

		foreach (Planet pl in star.Planets)
		{
			script = pl.Star.GetComponent<PlanetOrbit>();
			script.speed = (float)pl.Speed;
			script.toRun = flag ? true : false;

			// prepare for the label to be attached to the planet
			if (!pl.Giant)
			{
				sname = "Label" + pl.Orbit.ToString();
				otext = GameObject.Find(sname);

				GUIText gt = otext.GetComponent<GUIText>();
				gt.GetComponent<NameOrbit>().target = pl.Star.transform;
				gt.GetComponent<NameOrbit>().planet = pl;
				gt.GetComponent<NameOrbit>().pText = gt;
			}

			// prepare for the spotlight for the planet
			sname = "Spot" + pl.Orbit.ToString();
			ospot = GameObject.Find(sname);

			ospot.GetComponent<SpotOrbit>().target = pl.Star.transform;
		}

		return true;
	}

	public static StarSystem ScrollStarSystems(List<StarSystem> lstars, StarSystem star, int offset)			// flag = display only conquered
	{
		int count = 0;
		int idx = 0;

		foreach (StarSystem ss in lstars)
		{
			if (ss.Location == star.Location)
			{
				idx = count + offset;

				if (idx < 0)
				{
					idx += lstars.Count;

					if (idx < 0)
						return star;			// out of range
				}
				else if (idx >= lstars.Count)
				{
					idx -= lstars.Count;

					if (idx >= lstars.Count)
						return star;			// out of range
				}
			}

			count++;
		}

		if (idx >= 0 && idx < lstars.Count)
			return lstars[idx];

		return star;
	}

}
